/**
 * SysArticleServiceImpl.java -- 2017-10-18 21:15:13 作者：欧增奇 -- 代码生成器自动生成 联系方式：425752797@qq.com http://www.ouzengqi.com/
 */
package com.ozq.sys.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hankcs.hanlp.HanLP;
import com.ozq.common.page.Page;
import com.ozq.common.page.PageUtil;
import com.ozq.common.util.CommonUtils;
import com.ozq.common.util.UuidUtils;
import com.ozq.sys.dao.entity.SysArticle;
import com.ozq.sys.dao.entity.SysText;
import com.ozq.sys.dao.mapper.SysArticleMapper;
import com.ozq.sys.dao.mapper.SysTextMapper;
import com.ozq.sys.service.inter.SysArticleService;

/**
 * <文章表接口实现> <功能详细描述>
 * 
 * @author 欧增奇
 * @version [V2.0, 2017-10-18 21:15:13]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Service("sysArticleService")
public class SysArticleServiceImpl implements SysArticleService
{
    static Logger logger = LoggerFactory.getLogger(SysArticleServiceImpl.class);

    /**
     * 文章表Mapper[SysArticle]
     */
    @Autowired
    private SysArticleMapper sysArticleMapper;

    /**
     * 系统-文本表Mapper[SysText]
     */
    @Autowired
    private SysTextMapper sysTextMapper;

    /** ------------------------------------公共-工具------------------------------------ **/
    /**
     * 分页公共实现
     */
    @Override
    public Page pageManage(Page page)
    {
        logger.debug("debug page: {}", page);

        // 默认每页10条记录
        if (page.getEveryPage() <= 0)
            page.setEveryPage(10);

        // 默认第一页
        if (page.getCurrentPage() <= 0)
            page.setCurrentPage(1);

        return PageUtil.createPage(page.getEveryPage(), page.getTotalCount(), page.getCurrentPage());
    }

    /**
     * 缓存清理
     */
    @Override
    public void clearCache()
    {
        logger.debug("清理文章表缓存成功:{}", "sysArticle");
    }

    /** ------------------------------------公共-业务------------------------------------ **/
    /** --公共-业务-统计-- **/
    /**
     * 统计文章表所有的记录数
     * 
     * @return int
     */
    @Override
    public int countAll()
    {
        return sysArticleMapper.countAll();
    }

    /**
     * 按照条件精确统计文章表
     * 
     * @param sysArticle
     * @return int
     */
    @Override
    public int countBy(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null)
            return 0;

        return sysArticleMapper.countBy(sysArticle);
    }

    /**
     * 按照条件模糊统计文章表
     * 
     * @param sysArticle
     * @return int
     */
    @SuppressWarnings("deprecation")
    @Override
    public int countLike(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null)
            return 0;

        String selectSQL = "";
        selectSQL += " SELECT COUNT(1) countVal";
        selectSQL += " FROM sys_article sa";

        Map<String, Object> whereMap = new HashMap<>();
        whereMap.put("type_code", sysArticle.getTypeCode());
        whereMap.put("article_status", sysArticle.getArticleStatus());
        whereMap.put("user_code", sysArticle.getUserCode());
        selectSQL = CommonUtils.getSelectSQLWhere(whereMap, true, selectSQL);

        selectSQL += " limit 1";

        List<Map<String, Object>> listMap = sysArticleMapper.selectCustom(selectSQL);
        if (listMap == null || listMap.isEmpty())
            return 0;

        Long countVal = (Long) listMap.get(0).get("countVal");
        return countVal.intValue();
    }

    /** --公共-业务-添加-- **/
    /**
     * 插入文章表
     * 
     * @param sysArticle
     * @return sysArticle
     */
    @Override
    public SysArticle add(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null || StringUtils.isBlank(sysArticle.getArticleTitle()) || StringUtils.isBlank(sysArticle.getArticleSynopsis()))
            return null;

        // 过滤数据
        sysArticle.setArticleTitle(CommonUtils.filterScript(sysArticle.getArticleTitle()));
        sysArticle.setArticleSynopsis(CommonUtils.filterScript(sysArticle.getArticleSynopsis()));

        // 插入内容
        SysText sysText = new SysText();
        // 查询原数据
        if (StringUtils.isNotBlank(sysArticle.getArticleCode()))
        {
            SysArticle newSysArticle = new SysArticle();
            newSysArticle.setArticleCode(sysArticle.getArticleCode());
            newSysArticle.setStartLine(0);
            newSysArticle.setEndLine(1);
            List<SysArticle> list = sysArticleMapper.listBy(newSysArticle);
            if (list != null && list.size() > 0)
            {
                newSysArticle = list.get(0);
                sysText.setTextCode(newSysArticle.getTextCode());
                List<SysText> listText = sysTextMapper.listBy(sysText);
                if (listText != null && listText.size() > 0)
                {
                    sysText = listText.get(0);
                    // 验证权限是否相同
                    if (!StringUtils.equals(newSysArticle.getUserCode(), sysArticle.getUserCode()))
                        return null;

                    sysArticle.setArticleId(newSysArticle.getArticleId());
                    sysArticle.setTypeCode(newSysArticle.getTypeCode());
                    sysText.setTextCode(newSysArticle.getTextCode());
                    sysText.setTextContent(sysArticle.getArticleSynopsis());
                    sysTextMapper.update(sysText);
                } else
                {
                    // 插入内容
                    sysText.setTextCode(UuidUtils.shortUuid());
                    sysText.setTextContent(sysArticle.getArticleSynopsis());
                    sysTextMapper.insert(sysText);
                }
            }
        } else
        {
            // 插入内容
            sysText.setTextCode(UuidUtils.shortUuid());
            sysText.setTextContent(sysArticle.getArticleSynopsis());
            sysTextMapper.insert(sysText);
        }

        List<String> imgs = getImgStr(sysArticle.getArticleSynopsis());
        sysArticle.setArticleCoverUrl(imgs.size() <= 0 ? null : imgs.get(0));

        // 去除网页数据<[.[^<]]*>
        String content = sysArticle.getArticleSynopsis().replaceAll("<.*?>", "");
        // 自定提取简介
        sysArticle.setArticleSynopsis(HanLP.getSummary(content, 98));

        // 分词器
        List<String> keywordList = HanLP.extractKeyword(sysArticle.getArticleTitle(), 1);
        List<String> contentList = HanLP.extractKeyword(content, 3);
        keywordList.addAll(contentList);
        sysArticle.setArticleKeyWord(StringUtils.join(keywordList, ","));
        sysArticle.setTextCode(sysText.getTextCode());
        sysArticle.setArticleStatus(0);
        if (sysArticle.getArticleId() == null)
        {
            sysArticle.setArticleCode(UuidUtils.shortUuid());
            sysArticleMapper.insert(sysArticle);
        } else
        {
            sysArticleMapper.update(sysArticle);
        }
        return sysArticle;
    }

    /**
     * 插入文章表集合
     * 
     * @param sysArticle
     * @return boolean
     */
    @Override
    public boolean addList(List<SysArticle> sysArticles)
    {
        logger.debug("debug sysArticles: {}", sysArticles);

        if (sysArticles == null || sysArticles.isEmpty())
            return false;

        List<SysArticle> inserts = filterEmpty(sysArticles);
        if (inserts.isEmpty())
            return false;

        sysArticleMapper.insertList(inserts);
        return true;
    }

    /**
     * 批量插入文章表，当id存在更新这条数据，不存在插入这条数据（注意：会影响所有字段）
     * 
     * @param sysArticles
     * @return boolean
     */
    @Override
    public boolean addUpdateList(List<SysArticle> sysArticles)
    {
        logger.debug("debug sysArticles: {}", sysArticles);

        if (sysArticles == null || sysArticles.isEmpty())
            return false;

        List<SysArticle> inserts = filterEmpty(sysArticles);
        if (inserts.isEmpty())
            return false;

        sysArticleMapper.insertUpdateList(inserts);
        return true;
    }

    /** --公共-业务-查询-- **/
    /**
     * 按照文章表查询,如果存在id，则用id查询(本方法只会返回一条数据，当查询有1条以上返回null)
     * 
     * @param sysArticle
     * @return sysArticle
     */
    @Override
    public SysArticle find(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null)
            return null;

        if (sysArticle.getArticleId() != null)
            return sysArticleMapper.selectById(sysArticle.getArticleId());

        sysArticle.setStartLine(0);
        sysArticle.setEndLine(1);
        List<SysArticle> list = sysArticleMapper.listBy(sysArticle);
        if (list == null || list.isEmpty())
            return null;

        return list.get(0);
    }

    /**
     * 按照id查询文章表
     * 
     * @param articleId
     * @return sysArticle
     */
    @Override
    public SysArticle findById(Integer articleId)
    {
        logger.debug("debug articleId: {}", articleId);

        if (articleId == null)
            return null;

        return sysArticleMapper.selectById(articleId);
    }

    /**
     * 按照ids查询文章表
     * 
     * @param articleIds
     * @return sysArticle集合
     */
    @Override
    public List<SysArticle> findByIds(List<Integer> articleIds)
    {
        logger.debug("debug articleIds: {}", articleIds);

        if (articleIds == null || articleIds.isEmpty())
            return null;

        return sysArticleMapper.selectByIds(articleIds);
    }

    /**
     * 按照条件精确查询文章表返回集合方法
     * 
     * @param sysArticle
     * @return sysArticle
     */
    @Override
    public List<SysArticle> listBy(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null)
            return null;

        return sysArticleMapper.listBy(sysArticle);
    }

    /**
     * 按照条件模糊查询文章表返回集合方法
     * 
     * @param sysArticle
     * @return sysArticle集合
     */
    @Override
    public List<SysArticle> listLike(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null)
            return null;

        return sysArticleMapper.listLike(sysArticle);
    }

    /**
     * 按照分页条件精确查询文章表返回集合方法
     * 
     * @param sysArticle
     * @return sysArticle集合
     */
    @Override
    public List<SysArticle> listPageBy(Page page, SysArticle sysArticle)
    {
        logger.debug("debug page: {}", page);
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null)
            sysArticle = new SysArticle();

        if (page != null)
        {
            sysArticle.setStartLine(page.getBeginIndex());
            sysArticle.setEndLine(page.getEveryPage());
        }

        if (sysArticle.getOrderBy() == null)
            sysArticle.setOrderBy(SysArticle.FIELD_ARTICLE_UPDATA_TIME + SysArticle.ORDER_BY_DESC);

        return sysArticleMapper.listBy(sysArticle);
    }

    /**
     * 按照分页条件模糊查询文章表返回集合方法
     * 
     * @param sysArticle
     * @return sysArticle集合
     */
    @SuppressWarnings("deprecation")
    @Override
    public List<Map<String, Object>> listPageLike(Page page, SysArticle sysArticle)
    {
        logger.debug("debug page: {}", page);
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null)
            sysArticle = new SysArticle();

        String selectSQL = "";
        selectSQL += " SELECT sa.*,(";
        selectSQL += "     SELECT user_nick_name";
        selectSQL += "     FROM sys_user su";
        selectSQL += "     WHERE su.user_code=sa.user_code";
        selectSQL += " ) AS user_nick_name,(";
        selectSQL += "     SELECT COUNT(1)";
        selectSQL += "     FROM sys_comment su";
        selectSQL += "     WHERE su.article_code=sa.article_code AND comment_type=1";
        selectSQL += " ) AS count_comment";
        selectSQL += " FROM sys_article sa";

        Map<String, Object> whereMap = new HashMap<>();
        whereMap.put("type_code", sysArticle.getTypeCode());
        whereMap.put("article_status", sysArticle.getArticleStatus());
        whereMap.put("article_main", sysArticle.getArticleMain());
        whereMap.put("user_code", sysArticle.getUserCode());

        // 分词提取
        if (StringUtils.isNotBlank(sysArticle.getArticleKeyWord()))
        {
            List<String> keys = HanLP.extractKeyword(sysArticle.getArticleKeyWord(), 1);
            if (keys != null && !keys.isEmpty())
                whereMap.put(CommonUtils.FIND_IN_SET + "article_key_word", keys.get(0));
        }

        selectSQL = CommonUtils.getSelectSQLWhere(whereMap, true, selectSQL);
        if (StringUtils.isEmpty(sysArticle.getOrderBy()))
            selectSQL += " ORDER BY article_top DESC,article_time DESC";
        else if (StringUtils.isNotBlank(sysArticle.getOrderBy()))
            selectSQL += " ORDER BY " + sysArticle.getOrderBy();

        if (page != null)
            selectSQL += " limit " + page.getBeginIndex() + ", " + page.getEveryPage();

        return sysArticleMapper.selectCustom(selectSQL);
    }

    /** --公共-业务-修改-- **/
    /**
     * 修改文章表
     * 
     * @param sysArticle
     * @return boolean
     */
    @Override
    public boolean update(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null || sysArticle.getArticleId() == null)
            return false;

        sysArticleMapper.update(sysArticle);
        return true;
    }

    /**
     * 批量修改文章表
     * 
     * @param sysArticles
     * @return boolean
     */
    @Override
    public boolean updateList(List<SysArticle> sysArticles)
    {
        logger.debug("debug sysArticles: {}", sysArticles);

        if (sysArticles == null)
            return false;

        List<SysArticle> news = new ArrayList<SysArticle>();
        for (SysArticle sysArticle : sysArticles)
            if (sysArticle != null && sysArticle.getArticleId() != null)
                news.add(sysArticle);

        if (news.isEmpty())
            return false;

        sysArticleMapper.updateList(news);
        return true;
    }

    /** --公共-业务-删除-- **/
    /**
     * 指定id删除
     * 
     * @param articleId
     * @return boolean
     */
    @Override
    public boolean deleteById(Integer articleId)
    {
        logger.debug("debug articleId: {}", articleId);

        if (articleId == null)
            return false;

        sysArticleMapper.deleteById(articleId);
        return true;
    }

    /**
     * 批量删除指定ids
     * 
     * @param articleId
     * @return boolean
     */
    @Override
    public boolean deleteByIds(List<Integer> articleIds)
    {
        logger.debug("debug articleIds: {}", articleIds);

        if (articleIds == null || articleIds.isEmpty())
            return false;

        sysArticleMapper.deleteByIds(articleIds);
        return true;
    }

    /**
     * 按照条件精确删除文章表
     * 
     * @param sysArticle
     * @return boolean
     */
    @Override
    public boolean deleteBy(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null)
            return false;

        sysArticleMapper.deleteBy(sysArticle);
        return true;
    }

    /**
     * 按照条件模糊删除文章表
     * 
     * @param sysArticle
     * @return boolean
     */
    @Override
    public boolean deleteLike(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        if (sysArticle == null)
            return false;

        sysArticleMapper.deleteLike(sysArticle);
        return true;
    }

    /** --公共-业务-自定义-- **/
    /**
     * 自定义方法
     * 
     * @param sysArticle
     * @return map集合
     */
    @Override
    public List<Map<String, Object>> custom(SysArticle sysArticle)
    {
        logger.debug("debug sysArticle: {}", sysArticle);

        // 自己实现自己的业务
        // sysArticleMapper.selectCustom(selectSQL);
        return null;
    }

    /** ------------------------------------私有-方法------------------------------------ **/
    /**
     * 过滤参数为空
     * 
     * @param sysArticles
     * @return sysArticle集合
     */
    private List<SysArticle> filterEmpty(List<SysArticle> sysArticles)
    {
        List<SysArticle> news = new ArrayList<SysArticle>();
        for (SysArticle sysArticle : sysArticles)
            if (sysArticle != null)
                news.add(sysArticle);
        return news;
    }

    /**
     * 得到网页中图片的地址
     */
    private List<String> getImgStr(String htmlStr)
    {
        List<String> pics = new ArrayList<>();
        String img = "";
        Pattern p_image;
        Matcher m_image;
        // String regEx_img = "<img.*src=(.*?)[^>]*?>"; //图片链接地址
        String regEx_img = "<img.*lay-src\\s*=\\s*(.*?)[^>]*?>";
        p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
        m_image = p_image.matcher(htmlStr);
        while(m_image.find())
        {
            // 得到<img />数据
            img = m_image.group();
            // 匹配<img>中的src数据
            Matcher m = Pattern.compile("lay-src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
            while(m.find())
            {
                pics.add(m.group(1));
            }
        }
        return pics;
    }
}